import ij.IJ;
import ij.ImagePlus;
import ij.process.ImageProcessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class normalize_channel {

	public void normalize(ImagePlus imp, ImagePlus mask_Channel1,
			ImagePlus mask_Channel2, String channel_type) {

		ImageProcessor mask_ip_1 = mask_Channel1.getProcessor();
		ImageProcessor mask_ip_2 = mask_Channel2.getProcessor();

		ImageProcessor ip = imp.getProcessor();

		int width = ip.getWidth();
		int height = ip.getHeight();

		int mask_pixel_1, mask_pixel_2, channel_pixel, g, b;

		List<Integer> PixelList = new ArrayList<Integer>();

		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {

				mask_pixel_1 = mask_ip_1.getPixel(i, j);
				mask_pixel_2 = mask_ip_2.getPixel(i, j);

				channel_pixel = ip.getPixel(i, j);

				if (mask_pixel_1 == 255 && mask_pixel_2 == 255) {

					PixelList.add(channel_pixel);
				} else
					ip.putPixel(i, j, 0);

			}
		}

		Collections.sort(PixelList);
		double median = 0;

		if (PixelList.size() % 2 == 1)
			median = PixelList.get((PixelList.size() + 1) / 2 - 1);
		else {
			double lower = PixelList.get(PixelList.size() / 2 - 1);
			double upper = PixelList.get(PixelList.size() / 2);

			median = (lower + upper) / 2.0;
		}

		Iterator<Integer> PixelIterator = PixelList.iterator();

		int pixelValueSum = 0;
		int mean = 0;
		double stdDev = 0;

		while (PixelIterator.hasNext()) {

			pixelValueSum = pixelValueSum + PixelIterator.next();

		}
		mean = pixelValueSum / PixelList.size();

		double devSq = 0.0;
		for (double x : PixelList) {
			double dev = x - mean;
			devSq += dev * dev;
		}
		stdDev = Math.sqrt(devSq / (PixelList.size() - 1));

		System.out.println("Size " + PixelList.size());
		System.out.println("Mean " + mean);
		System.out.println("Median " + median);
		System.out.println("Stddev " + stdDev);

	
		double[] bucket = new double[Analysis_.bucket_size];
		bucket[0] = mean;
		int p=1,q=1,cnt=1;
		
		while (cnt < Analysis_.bucket_size)
		{
			bucket[p] = mean + q*stdDev;
			cnt++;
			
			if(cnt == Analysis_.bucket_size)
				break;
			else
			{
				bucket[p+1]= mean - q* stdDev;
				cnt ++;
				p = p + 2;
				q = q+1;
			}
		}
		
		Arrays.sort(bucket);
		
		for(int i =0; i< Analysis_.bucket_size; i++){	
			System.out.print(" buc:"+bucket[i]);
			}

		boolean flag = false;
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {

				flag = false;
				mask_pixel_1 = mask_ip_1.getPixel(i, j);
				mask_pixel_2 = mask_ip_2.getPixel(i, j);
				channel_pixel = ip.getPixel(i, j);

				if (mask_pixel_1 == 255 && mask_pixel_2 == 255) {
				
				if(channel_pixel >= 0 && channel_pixel < bucket[0])
					{
					ip.putPixel(i, j, (int) bucket[0]);
					flag = true;
					}
				else{
				for( int m =0; m< Analysis_.bucket_size-1 ; m++ )
				{
					if (channel_pixel >= bucket[m] && channel_pixel <bucket[m+1])
					{
						ip.putPixel(i, j, (int) bucket[m]);
						flag = true;
					}
					
				}
				}
				if(flag == false)
					ip.putPixel(i, j, (int) (stdDev +bucket[Analysis_.bucket_size-1]));
							
				}
			}
		}
		
	/*

		int count1, count2, count3, count4;
		count1 = 0;
		count2 = 0;
		count3 = 0;
		count4 = 0;

    		double bucket1, bucket2, bucket3;
           	bucket1 = mean - stdDev;
			bucket2 = mean + stdDev;
		    bucket3 = mean + stdDev * 2;
           for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {

				mask_pixel_1 = mask_ip_1.getPixel(i, j);
				mask_pixel_2 = mask_ip_2.getPixel(i, j);
				channel_pixel = ip.getPixel(i, j);

				if (mask_pixel_1 == 255 && mask_pixel_2 == 255) {

					if (channel_pixel >= 0 && channel_pixel < (mean - stdDev)) {
						count1++;
						ip.putPixel(i, j, (int) bucket1);
					} else if (channel_pixel >= (mean - stdDev)
							&& channel_pixel < mean) {
						ip.putPixel(i, j, (int) mean);
						count2++;
					} else if (channel_pixel >= mean
							&& channel_pixel < mean + stdDev) {
						ip.putPixel(i, j, (int) bucket2);
						count3++;
					} else {
						ip.putPixel(i, j, (int) bucket3);
						count4++;
					}

				}
			}

		}

		System.out.println("Count1 " + count1);
		System.out.println("Count2 " + count2);
		System.out.println("Count3  " + count3);
		System.out.println("Count4  " + count4);
       */       
		
		
		
		imp.updateAndDraw();
		IJ.run(imp, "Enhance Contrast", "saturated=0.4");

		if (channel_type == "red") {
			IJ.run(imp, "Red", "");
		} else {
			IJ.run(imp, "Green", "");
		}

	}
}